﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed
#pragma once

#include "GcmpModelInterface.h"
#include "IElement.h"
#include "OwnerPtr.h"
#include "ElementCreationOptions.h"

namespace gcmp
{
    class IPlane;
    /// \brief 工作平面的接口。
    /// 
    /// 工作平面主要在ModelVeiw中使用，为ModelView提供基准平面。每个视图可以有一个工作平面。
    /// 一个文档还可以有一个全局的工作平面，如果激活全局工作平面，不论切换到那个视图，都使用全
    /// 局工作平面。如在编辑模式下，工作全局工作平面会被激活。
    class GCMP_MODEL_INTERFACE_EXPORT IWorkPlane : public IElement
    {
        DEFINE_CAST_DERIVED(gcmp::IWorkPlane, gcmp::IElement);
    public:
        /// \brief 析构函数。
        virtual ~IWorkPlane();
#pragma region Static
        /// \brief 获取所有工作平面。
        ///
        /// 或取所有工作平面的指针。
        /// \param pDoc 文档指针。
        /// \return 返回工作平面的接口指针数组。
        static std::vector<IWorkPlane*> GetAllWorkPlanes(const IDocument* pDoc);
        /// \brief 获取所有工作平面Id。
        ///
        /// 或取所有工作平面的Id。
        /// \param pDoc 文档指针。
        /// \return 返回工作平面的ElmentId数组。
        static std::vector<ElementId> GetAllWorkPlaneIds(const IDocument* pDoc);

        /// \brief 创建工作平面。
        ///
        /// 创建一个工作平面。
        /// \param pDoc 文档指针。
        /// \param pPlane 工作平面的输入平面数据。
        /// \param name 工作平面的名称。
        /// \param creationOption 元素创建选项,可设置为永久(Normal)或临时对象
        /// \return 返回一个工作平面的接口指针。
        static IWorkPlane* Create(IDocument* pDoc, const IPlane* pPlane, const std::wstring& name, ElementCreationOptions creationOption = ElementCreationOptions::Normal);
#pragma endregion Static
        /// \brief 获取工作平面引用的平面的ElementId。
        ///
        /// 工作平面可能会引用其他平面，比如设置某个形体的表面作为工作平面，这时，会创建一个
        /// 辅助参考平面引用形体的表面，并且用工作平面引用这个辅助参考平面。
        /// \return 返回工作平面引用的平面的ElementId，如果工作平面没有引用其他平面，
        /// 返回InvalidId。
        virtual gcmp::ElementId GetReferencedPlaneId() const = 0;
        /// \brief 设置工作平面引用的平面的ElementId。
        ///
        /// 如果工作平面引用了某个对象，其平面数据会与引用的对象关联。
        /// \param referencePlaneId 工作平面引用的对象的ElementId。
        /// \return 如果设置成功，返回true；否则返回false。
        virtual bool SetReferencedPlaneId(const gcmp::ElementId& referencePlaneId) = 0;

        /// \brief 设置位置报告组件
        /// \param opElementPositionReportComponent 位置报告组件
        /// \return bool
        virtual bool SetElementPositionReportComponent(OwnerPtr<IElementPositionReportComponent> opElementPositionReportComponent) = 0;

        /// \brief 获取工作平面的平面数据。
        ///
        /// \return 返回工作平面的平面数据。
        virtual const IPlane* GetGeometryPlane() const = 0;
        /// \brief 设置工作平面的平面数据。
        ///
        /// \param plane 工作平面新的平面数据。
        /// \return 如果设置成功，返回true；否则返回false。
        virtual bool SetGeometryPlane(const IPlane* pPlane) = 0;
        /// \brief 获取参照平面的几何平面的RegenDataId。
        /// \return 返回参照平面的几何平面的RegenDataId。
        virtual RegenDataId GetPlaneRdId() const = 0;
        virtual void MarkPlaneRdId() = 0;

        /// \brief  获取ReferencedPlaneId的关联更新id 
        /// \return 获取的ReferencedPlaneId的RegenDataId
        virtual RegenDataId GetReferencedPlaneIdRdId() const = 0;

        /// \brief 标记ReferencedPlaneId已发生改变
        virtual void MarkReferencedPlaneIdRdId() = 0;

    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();
    };
}



